#include "stdafx.h"
#include <Ws2bth.h>
#include "GPScomm.h"
#include <iostream>
#include <fstream>

GPScomm::GPScomm(void)
{
	useCOM0 = useCOM1 = useCOM2 = useCOM3 = useCOM4 = false;
	COMport0 = COMport1 = COMport2 = COMport3 = COMport4 = NULL;
	output_file=NULL;
	//BUFF = NULL;
	server_socket=-1;
	server_buffer_length=0;
	memset(server_buffer,NULL,5*buffer_size); // server_buffer[0]='\0';
	connection_stopped = false;

	server_port = 5000;
	ip_address = L"192.168.2.2";

	//TODO: Store Default Values somewhere so we don't have to reset them every time
		//Registry seems promising, but confusing 
}

GPScomm::~GPScomm(void)
{
		if(COMport0)
		{
			CloseHandle(COMport0);
		}

	    if(COMport1)
		{
			CloseHandle(COMport1);
		}

		if(COMport2)
		{
			CloseHandle(COMport2);
		}

		if(COMport3)
		{
			CloseHandle(COMport3);
		}

		if(COMport4)
		{
			CloseHandle(COMport4);
		}
}

void GPScomm::dontUseCOM(int port)
{
	switch(port)
	{
	case 0:
		useCOM0 = false;
		break;
	case 1:
		useCOM1 = false;
		break;
	case 2:
		useCOM2 = false;
		break;
	case 3:
		useCOM3 = false;
		break;
	case 4:
		useCOM4 = false;
		break;
	}
}

void GPScomm::useCOM(int port)
{
	switch(port)
	{
	case 0:
		useCOM0 = true;
		break;
	case 1:
		useCOM1 = true;
		break;
	case 2:
		useCOM2 = true;
		break;
	case 3:
		useCOM3 = true;
		break;
	case 4:
		useCOM4 = true;
		break;
	}
}

bool GPScomm::Connect(void)
{
	int return_value=0;
	if(useCOM0)
	{
		if(OpenClientConnection(0))
		{
			LPCTSTR message = L"COM port 0 open, succeeded"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
			return_value++;
		}else {
			LPCTSTR message = L"COM port 0 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
//			useCOM0=false;
		}
	}
	
	if(useCOM1)
	{
		if(OpenClientConnection(1))
		{
			LPCTSTR message = L"COM port 1 open, succeeded"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
			return_value++;
		}else {
			LPCTSTR message = L"COM port 1 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
//			useCOM1=false;
		}
	}

	if(useCOM2)
	{
		if(OpenClientConnection(2))
		{
			LPCTSTR message = L"COM port 2 open, succeeded"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
			return_value++;
		}else {
			LPCTSTR message = L"COM port 2 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
//			useCOM2=false;
		}
	}

	if(useCOM3)
	{
		if(OpenClientConnection(3))
		{
			LPCTSTR message = L"COM port 3 open, succeeded"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
			return_value++;
//			SendMessage(HWND_BROADCAST, WM_GPS_ADDED, 1, 0);
		}else {
			LPCTSTR message = L"COM port 3 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
//			useCOM3=false;
		}
	}

	if(useCOM4)
	{
		if(OpenClientConnection(4))
		{
			LPCTSTR message = L"COM port 4 open, succeeded"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
			return_value++;
		}else {
			LPCTSTR message = L"COM port 4 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
//			useCOM4=false;
		}
	}
	return((bool)return_value);
}

int GPScomm::OpenClientConnection(int port)
{ // http://msdn.microsoft.com/en-us/library/ms923949.aspx for CreateFile(parameters)
		// instructions say to use OPEN_EXISTING when opening a COM port
	COMMTIMEOUTS timeouts;
	switch(port)
	{
	case 0:
		COMport0 = CreateFile(L"COM0:",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
		if (COMport0 == NULL){
			LPCTSTR message = L"COM port 0 open, failed"; 
			LPCTSTR messageCaption = L"Dialog";
			MessageBoxW(NULL,message, messageCaption, MB_OK);
		}
		GetCommTimeouts(COMport0,&timeouts);
		timeouts.ReadTotalTimeoutConstant=2000; //milliseconds
		SetCommTimeouts(COMport0,&timeouts);
		return((int)COMport0);
		break;
	case 1:
		COMport1 = CreateFile(L"COM1:",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//		GetCommTimeouts(COMport1,&timeouts);
//		timeouts.ReadTotalTimeoutConstant=2000; //milliseconds
//		SetCommTimeouts(COMport1,&timeouts);
		return((int)COMport1);
		break;
	case 2:
		COMport2 = CreateFile(L"COM2:",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//		GetCommTimeouts(COMport2,&timeouts);
//		timeouts.ReadTotalTimeoutConstant=2000; //milliseconds
//		SetCommTimeouts(COMport2,&timeouts);
		return((int)COMport2);
		break;
	case 3:
		COMport3 = CreateFile(L"COM3:",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//		GetCommTimeouts(COMport3,&timeouts);
//		timeouts.ReadTotalTimeoutConstant=2000; //milliseconds
//		SetCommTimeouts(COMport3,&timeouts);
		return((int)COMport3);
		break;
	case 4:
		COMport4 = CreateFile(L"COM4:",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//		GetCommTimeouts(COMport4,&timeouts);
//		timeouts.ReadTotalTimeoutConstant=2000; //milliseconds
//		SetCommTimeouts(COMport4,&timeouts);
		return((int)COMport4);
		break;
	}
	return 0;
}

void GPScomm::query_GPS_configuration(int port)
{ // http://msdn.microsoft.com/en-us/library/aa365747(VS.85).aspx WriteFile()

	DWORD error_value;
	DWORD number_of_bytes_successfully_read_into_buffer_for_query;
	DWORD dword_buffer_size=buffer_size;
	char query_buffer[buffer_size];
	memset(query_buffer,NULL,buffer_size);
	strcpy(query_buffer,"$PGRMC1E");
	number_of_bytes_successfully_read_into_buffer_for_query=strlen(query_buffer);

	switch(port)
	{
	case 0:
		if(COMport0)
		{
			if(0== WriteFile(COMport0,query_buffer,number_of_bytes_successfully_read_into_buffer_for_query,NULL,NULL))
			{			
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write from COM0",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
				number_of_bytes_successfully_read_into_buffer_for_query=0;
				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				ReadFile(COMport0,query_buffer,dword_buffer_size,&number_of_bytes_successfully_read_into_buffer_for_query,NULL);
				query_buffer[number_of_bytes_successfully_read_into_buffer_for_query]='\0';
				MessageBoxW(NULL,(LPCWSTR)query_buffer,(LPCWSTR)query_buffer,MB_OK);
			//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
			}
		}
		break;
	}
}

void GPScomm::send_binary_mode_string()
{ // http://msdn.microsoft.com/en-us/library/aa365747(VS.85).aspx WriteFile()
	DWORD error_value;
	DWORD byteswritten;
	if(useCOM0)
	{
			//10 0A 02 26 00 CE 10 03 HEX string needed to send NMEA sentences in the unit is in binary mode
//			WriteFile(COMport0, L"\x10\x0A\x02\x26\x00\xCE\x10\x03", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x10", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x0A", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x02", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x26", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x00", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\xCE", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x10", (DWORD)8,&byteswritten,NULL);
//			WriteFile(COMport0, L"\x03", (DWORD)8,&byteswritten,NULL);
					// following 3.1.4 format guide
			WriteFile(COMport0, L"$PGRMC1,,2,,,,,,,N,1,1,2*hh\r\n", (DWORD)31,&byteswritten,NULL);
					// then request that the device reboot itself to get binary output started
			if(0 == WriteFile(COMport0, L"$PGRMCI,,,,,,,*hh\r\n", (DWORD)21,&byteswritten,NULL))
			{ // puts GPS is default transmit setting
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write to COM0",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
//				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
				if(byteswritten==21)
				{
//					MessageBoxW(NULL,(LPCWSTR)L"21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
				else
				{
//					MessageBoxW(NULL,(LPCWSTR)L"NO, 21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
			}
	}

	if(useCOM1)
	{
			WriteFile(COMport1, L"$PGRMC1,,2,,,,,,,N,1,1,2*hh\r\n", (DWORD)31,&byteswritten,NULL);
					// then request that the device reboot itself to get binary output started
			if(0 == WriteFile(COMport1, L"$PGRMCI,,,,,,,*hh\r\n", (DWORD)21,&byteswritten,NULL))
			{ // puts GPS is default transmit setting
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write to COM1",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
//				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
				if(byteswritten==21)
				{
//					MessageBoxW(NULL,(LPCWSTR)L"21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
				else
				{
//					MessageBoxW(NULL,(LPCWSTR)L"NO, 21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
			}
	}

	if(useCOM2)
	{
			WriteFile(COMport2, L"$PGRMC1,,2,,,,,,,N,1,1,2*hh\r\n", (DWORD)31,&byteswritten,NULL);
					// then request that the device reboot itself to get binary output started
			if(0 == WriteFile(COMport2, L"$PGRMCI,,,,,,,*hh\r\n", (DWORD)21,&byteswritten,NULL))
			{ // puts GPS is default transmit setting
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write to COM2",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
//				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
				if(byteswritten==21)
				{
//					MessageBoxW(NULL,(LPCWSTR)L"21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
				else
				{
//					MessageBoxW(NULL,(LPCWSTR)L"NO, 21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
			}
	}

	if(useCOM3)
	{
			WriteFile(COMport3, L"$PGRMC1,,2,,,,,,,N,1,1,2*hh\r\n", (DWORD)31,&byteswritten,NULL);
					// then request that the device reboot itself to get binary output started
			if(0 == WriteFile(COMport3, L"$PGRMCI,,,,,,,*hh\r\n", (DWORD)21,&byteswritten,NULL))
			{ // puts GPS is default transmit setting
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write to COM3",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
//				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
				if(byteswritten==21)
				{
//					MessageBoxW(NULL,(LPCWSTR)L"21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
				else
				{
//					MessageBoxW(NULL,(LPCWSTR)L"NO, 21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
			}
	}

	if(useCOM4)
	{
			WriteFile(COMport4, L"$PGRMC1,,2,,,,,,,N,1,1,2*hh\r\n", (DWORD)31,&byteswritten,NULL);
					// then request that the device reboot itself to get binary output started
			if(0 == WriteFile(COMport4, L"$PGRMCI,,,,,,,*hh\r\n", (DWORD)21,&byteswritten,NULL))
			{ // puts GPS is default transmit setting
				error_value = GetLastError();
				MessageBoxW(NULL,(LPCWSTR)L"Failed to write to COM4",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
			}
			else
			{
//				MessageBoxW(NULL,(LPCWSTR)L"Write Success",(LPCWSTR)L"Success",MB_OK);
				//WriteFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
				if(byteswritten==21)
				{
//					MessageBoxW(NULL,(LPCWSTR)L"21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
				else
				{
//					MessageBoxW(NULL,(LPCWSTR)L"NO, 21 bytes written",(LPCWSTR)L"Success",MB_OK);
				}
			}
	}
}


//h http://msdn.microsoft.com/en-us/library/aa365467(VS.85).aspx  ReadFile()

void GPScomm::read_binary_mode_string()
{
	DWORD error_value;
	HANDLE output_file=NULL;

	if(useCOM0)
	{
		memset(receive_buffer0,NULL,buffer_size);
		number_of_bytes_successfully_read_into_buffer0=0;
		if(0 == ReadFile(COMport0,receive_buffer0,buffer_size,&number_of_bytes_successfully_read_into_buffer0,NULL))// still returns 0
		{
			error_value = GetLastError();
			MessageBoxW(NULL,(LPCWSTR)L"Failed to read from COM0",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
		}
		else
		{
/*	if(k==0)
	{
		strncpy(backup,receive_buffer,buffer_size);
	}
	else if(k==1)
	{
		LPCTSTR compare_message;
		if(0 == strncmp(backup,receive_buffer,buffer_size))
		{
			compare_message = L"strncmp matched";
		}
		else
		{
			compare_message = L"strncmp NOT matched";
		}
		MessageBoxW(NULL,compare_message, compare_message, MB_OK);
	}
	*/
			LPCTSTR messageCaption = L"bytes read COM0";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
//			test.open("test.txt",std::ios::in|std::ios::binary);
//			test << receive_buffer; // does put some data in the file
//			test.close();
		}	
//		test.open("test.txt",std::ios::in|std::ios::binary);
//		if (WriteFile(COMport0, L"$PGRMO,,4*hh\r\n", (DWORD)14,NULL,NULL)){
//			ReadFile(COMport0,BUFF,(DWORD)500,NULL,NULL);
		
			//LPCTSTR messageCaption = L"Dialog";, std::ios::in|std::ios::binary
			//MessageBoxW(NULL,(LPCTSTR)BUFF, messageCaption, MB_OK);
//			test << BUFF;
//		}
		//	test.write(receive_buffer,(std::streamsize)number_of_bytes_successfully_read_into_buffer);
		//ReadFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
//		}
	
		//ReadFile(COMport0, L"$PGRMI,,,,,,,R", (DWORD)14,NULL,NULL);
	}

	if(useCOM1)
	{
		memset(receive_buffer1,NULL,buffer_size);
		number_of_bytes_successfully_read_into_buffer1=0;
		if(0 == ReadFile(COMport1,receive_buffer1,buffer_size,&number_of_bytes_successfully_read_into_buffer1,NULL))// still returns 0
		{
			error_value = GetLastError();
			MessageBoxW(NULL,(LPCWSTR)L"Failed to read from COM1",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
		}
		else
		{
			LPCTSTR messageCaption = L"bytes read COM1";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}	
//		break;
	}

	if(useCOM2)
	{
		memset(receive_buffer2,NULL,buffer_size);
		number_of_bytes_successfully_read_into_buffer2=0;
		if(0 == ReadFile(COMport2,receive_buffer2,buffer_size,&number_of_bytes_successfully_read_into_buffer2,NULL))// still returns 0
		{
			error_value = GetLastError();
			MessageBoxW(NULL,(LPCWSTR)L"Failed to read from COM2",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
		}
		else
		{
			LPCTSTR messageCaption = L"bytes read COM2";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}	
//		break;
	}

	if(useCOM3)
	{
		memset(receive_buffer3,NULL,buffer_size);
		number_of_bytes_successfully_read_into_buffer3=0;
		if(0 == ReadFile(COMport3,receive_buffer3,buffer_size,&number_of_bytes_successfully_read_into_buffer3,NULL))// still returns 0
		{
			error_value = GetLastError();
			MessageBoxW(NULL,(LPCWSTR)L"Failed to read from COM3",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
		}
		else
		{
			LPCTSTR messageCaption = L"bytes read COM3";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}	
	//	break;
	}

	if(useCOM4)
	{
		memset(receive_buffer4,NULL,buffer_size);
		number_of_bytes_successfully_read_into_buffer4=0;
		if(0 == ReadFile(COMport4,receive_buffer4,buffer_size,&number_of_bytes_successfully_read_into_buffer4,NULL))// still returns 0
		{
			error_value = GetLastError();
			MessageBoxW(NULL,(LPCWSTR)L"Failed to read from COM4",(LPCWSTR)L"Failure",MB_OK); // doesent pop up on phone for some reason
		}
		else
		{
			LPCTSTR messageCaption = L"bytes read COM4";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}	
	//	break;
	}
}

// Function to swap the upper and lower words in a double
// This is only necessary for the Ephemeris Data doubles
double
GPScomm::swap(double d)
{
	double a;
	unsigned char *dst = (unsigned char *)&a;
	unsigned char *src = (unsigned char *)&d;

	dst[0]=src[4];
	dst[1]=src[5];
	dst[2]=src[6];
	dst[3]=src[7];
	dst[4]=src[0];
	dst[5]=src[1];
	dst[6]=src[2];
	dst[7]=src[3];

	return a;
}

HANDLE
GPScomm::open_output_file()
{
	if(output_file == NULL)
	{
		wchar_t *messageCaption;
		DWORD error_value;

		output_file = CreateFile(L"GPSdata.txt",GENERIC_WRITE,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH,NULL);
		if(output_file == INVALID_HANDLE_VALUE)
		{
			messageCaption = L"Open GPSdata.txt failed";
			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}
	return(output_file);
}


void
GPScomm::close_output_file()
{
	if(output_file)
	{
		CloseHandle(output_file);
		output_file=NULL;
	}
}

void
GPScomm::store_read_buffers()
{
	wchar_t * messageCaption, *messageTitle;
	DWORD error_value, buffer_length;
	buffer_length = 5 * buffer_size;
	WriteFile(output_file,server_buffer,buffer_length,&error_value,NULL);
	if(buffer_length != error_value)
	{
		messageCaption = L"failed to store buffers";
		messageTitle = L"Failure";
		MessageBoxW(NULL,messageCaption, messageTitle, MB_OK);
	}
//	if(number_of_bytes_successfully_read_into_buffer0)
	{
//		WriteFile(output_file,receive_buffer0,number_of_bytes_successfully_read_into_buffer0,&error_value,NULL);
//		if(number_of_bytes_successfully_read_into_buffer0 == error_value)
		{
//			messageCaption = L"test.txt(0) write success";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}

//	if(number_of_bytes_successfully_read_into_buffer1)
	{
//		WriteFile(output_file,receive_buffer1,number_of_bytes_successfully_read_into_buffer1,&error_value,NULL);
//		if(number_of_bytes_successfully_read_into_buffer1 == error_value)
		{
//			messageCaption = L"test.txt(1) write success";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}

//	if(number_of_bytes_successfully_read_into_buffer2)
	{
//		WriteFile(output_file,receive_buffer2,number_of_bytes_successfully_read_into_buffer2,&error_value,NULL);
//		if(number_of_bytes_successfully_read_into_buffer2 == error_value)
		{
//			messageCaption = L"test.txt(2) write success";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}

//	if(number_of_bytes_successfully_read_into_buffer3)
	{
//		WriteFile(output_file,receive_buffer3,number_of_bytes_successfully_read_into_buffer3,&error_value,NULL);
//		if(number_of_bytes_successfully_read_into_buffer3 == error_value)
		{
//			messageCaption = L"test.txt(3) write success";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}

//	if(number_of_bytes_successfully_read_into_buffer4)
	{
//		WriteFile(output_file,receive_buffer4,number_of_bytes_successfully_read_into_buffer4,&error_value,NULL);
//		if(number_of_bytes_successfully_read_into_buffer4 == error_value)
		{
//			messageCaption = L"test.txt(4) write success";
//			MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
		}
	}
}

void
GPScomm::add_to_que( char data )
{
	#define DLE_BYTE 0x10
	#define ETX_BYTE 0x03

	if( rx_state == DAT )
	{
		if( data == DLE_BYTE )
		{
			rx_state = DLE;
		}
		else
		{
			in_que[ in_que_ptr++ ] = data;
		}
	}
	else if( rx_state == DLE )
	{
		if( data == ETX_BYTE )
		{
			rx_state = ETX;
		}
		else
		{
			rx_state = DAT;
			in_que[ in_que_ptr++ ] = data;
		}
	}
	else if( rx_state == ETX )
	{
		if( data == DLE_BYTE )
		{
			rx_state = DLE;
		}
	}

	if( in_que_ptr > 255 )
	{
		in_que_ptr = 0;
	}
}

void
GPScomm::parse_received_buffers()
{
	static __int8 previous_id, current_id;
	wchar_t * messageCaption;
	char *buffer=NULL;
	DWORD length;
	bool skip=true;
	for(int k=0;k<5;k++)
	{
		switch(k)
		{
			case 0:
				if(useCOM0)
				{
					skip=false;
					buffer = receive_buffer0;
					length = number_of_bytes_successfully_read_into_buffer0;
				}
				break;
			case 1:
				if(useCOM1)
				{
					skip=false;
					buffer = receive_buffer1;
					length = number_of_bytes_successfully_read_into_buffer1;
				}
				break;
			case 2:
				if(useCOM2)
				{
					skip=false;
					buffer = receive_buffer2;
					length = number_of_bytes_successfully_read_into_buffer2;
				}
				break;
			case 3:
				if(useCOM3)
				{
					skip=false;
					buffer = receive_buffer3;
					length = number_of_bytes_successfully_read_into_buffer3;
				}
				break;
			case 4:
				if(useCOM4)
				{
					skip=false;
					buffer = receive_buffer4;
					length = number_of_bytes_successfully_read_into_buffer4;
				}
				break;
		}

		if(skip == false)
		{
			if(buffer[0] == '\x10' && buffer[length-2] == '\x10' && buffer[length-1] == '\x03')
			{
				wchar_t strvalue[100];
//				messageCaption = L"PARSE: binary delimeters found";
//				MessageBoxW(NULL, messageCaption,strvalue, MB_OK);

				current_id = (__int8)buffer[1];
//				swprintf(strvalue,(const wchar_t *)"%d",current_id);
//				if(previous_id > current_id)
				{
//					messageCaption = L"previous > current Record ID";
//					MessageBoxW(NULL, messageCaption,strvalue, MB_OK);
				}
//				else if(previous_id < current_id)
				{
//					messageCaption = L"previous < current Record ID";
//					MessageBoxW(NULL, messageCaption,strvalue, MB_OK);
				}
//				else // previous_id == current_id
				{
//					messageCaption = L"previous and current Record IDs are the same";
//					MessageBoxW(NULL, messageCaption,strvalue, MB_OK);
				}
//				previous_id = current_id;
			}
			else
			{
				messageCaption = L"PARSE: binary delimeters NOT found";
//				MessageBoxW(NULL,messageCaption, messageCaption, MB_OK);
			}
		}	
	}
}

/*
	switch(port)
	{
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
	}
*/

bool
GPScomm::connect_to_server()
{
	//ASP: This code now uses the externally-configurable variables tcp_port and ip_address.
		//The hard-coded values have been preserved as defaults set in the constructor.
	bool server_connected;
	//u_short server_port = 2000;
	struct sockaddr_in ServAddr;
	if((server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
	{
		//DieWithError("socket() failed");
	}
	ServAddr.sin_family = AF_INET;	/* Internet address family */
	ServAddr.sin_addr.s_addr = inet_addr((char*)ip_address);	/* Server IP address */
	ServAddr.sin_port = htons(server_port);	/* Server port */
	if(connect(server_socket, (struct sockaddr *) &ServAddr,sizeof(ServAddr)) < 0)
	{
		//DieWithError("connect() failed");
		server_connected = false;
	}
	else
	{
		server_connected = true;
	}
	return(server_connected);
}

bool // returns true if successful, false if not
GPScomm::send_to_server()
{
	int send_return_value=-1;
	if(server_socket > -1)
	{
		//echoStringLen=strlen(echoString); // Determine input length  Send the string to the server
		send_return_value = send(server_socket,server_buffer,server_buffer_length, 0);
		if(send_return_value != server_buffer_length)
		{
			// DieWithError("send() sent a different number of bytes than expected");
			switch(send_return_value)
			{
				case WSANOTINITIALISED:
					//A successful WSAStartup call must occur before using this function.
					break;
				case WSAENETDOWN:
					//The network subsystem has failed.
					break;
				case WSAEACCES:
					//The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket option to enable use of the broadcast address.
					break;
				case WSAEINTR:
					//A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.
					break;
				case WSAEINPROGRESS:
					//A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback functio
					break;
				case WSAEFAULT:
					//The buf parameter is not completely contained in a valid part of the user address space.
					break;
				case WSAENETRESET:
					//The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.
					break;
				case WSAENOBUFS:
					//No buffer space is available.
					break;
				case WSAENOTCONN:
					//The socket is not connected.
					break;
				case WSAENOTSOCK:
					//The descriptor is not a socket.
					break;
				case WSAEOPNOTSUPP:
					//MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.
					break;
				case WSAESHUTDOWN:
					//The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.
					break;
				case WSAEWOULDBLOCK:
					//The socket is marked as nonblocking and the requested operation would block.
					break;
				case WSAEMSGSIZE:
					//The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.
					break;
				case WSAEHOSTUNREACH:
					//The remote host cannot be reached from this host at this time.
					break;
				case WSAEINVAL:
					//The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.
					break;
				case WSAECONNABORTED:
					//The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.
					break;
				case WSAECONNRESET:
					//The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
					break;
				case WSAETIMEDOUT:
					//The connection has been dropped, because of a network failure or because the system on the other end went down without notice.
					break;
			};
			return(false);
		}
		else
		{
			return(true);
		}
	}
	else
	{
		return(false);
	}
}

void
GPScomm::prepare_server_packet()
{// Timestamp | Type | Number of GPS Packets | Serialized GPS Packet | Serialized GPS Packet | (...)

	//timestamp
//	DateTime d1;
//	d1= DateTime::UtcNow();
	// Totally original code for CTime::GetCurrentTime
	CTime t;
//	t.tm_isdst=0;
	t = CTime::GetCurrentTime();

	__int8 type=1;
/*
1: Raw GPS Data : Content formatted according to Fig 2
2: Raw Ephemeris Data: Content formatted according to Fig 2
4: Request for Ephemeris Data:  No Content
8: DGPS-Calculated Position Data: Content formatted according to Fig  3
16 and up: Unused
*/
	__int8 Number_of_GPS_Packets=0;
	server_buffer[0]='\0';
	server_buffer_length=0;
	if(useCOM0)
	{
		Number_of_GPS_Packets++;
	}

	if(useCOM1)
	{
		// not mappable on the phone
	}

	if(useCOM2)
	{
		Number_of_GPS_Packets++;
	}

	if(useCOM3)
	{
		Number_of_GPS_Packets++;
	}

	if(useCOM4)
	{
		Number_of_GPS_Packets++;
	}
	char *time_object = (char *)&t;
	server_buffer[0]=time_object[0];
	server_buffer[1]=time_object[1];
	server_buffer[2]=time_object[2];
	server_buffer[3]=time_object[3];
	server_buffer[4]=time_object[4];
	server_buffer[5]=time_object[5];
	server_buffer[6]=time_object[6];
	server_buffer[7]=time_object[7];
	server_buffer[8]=(char)type;
	server_buffer[9]=(char)Number_of_GPS_Packets;
	server_buffer[10]='\0';
	server_buffer_length=10;
	if(useCOM0)
	{
		strcat(server_buffer,receive_buffer0);
		server_buffer_length = number_of_bytes_successfully_read_into_buffer0;
	}

	if(useCOM1)
	{
		// not mappable on the phone
	}

	if(useCOM2)
	{
		strcat(server_buffer,receive_buffer2);
		server_buffer_length = number_of_bytes_successfully_read_into_buffer2;
	}

	if(useCOM3)
	{
		strcat(server_buffer,receive_buffer3);
		server_buffer_length = number_of_bytes_successfully_read_into_buffer3;
	}

	if(useCOM4)
	{
		strcat(server_buffer,receive_buffer4);
		server_buffer_length = number_of_bytes_successfully_read_into_buffer4;
	}
}

void GPScomm::stopCollecting()
{
	connection_stopped = true;
}

bool GPScomm::collectionStopped()
{
	return connection_stopped;
}

LPCTSTR GPScomm::getIPAddress()
{
	return ip_address;
}
void GPScomm::setIPAddress(LPCTSTR ip)
{
	ip_address = ip;
}
u_short GPScomm::getTCPPort()
{
	return server_port;
}
void GPScomm::setTCPPort(u_short p)
{
	server_port = p;
}